﻿using System.Threading.Tasks;
using System.Threading;
using Microsoft.Extensions.Hosting;
using Adp;
using System;
using Adp.Common;
using System.Collections.Generic;
using Yqd.Models;
using System.Linq;
using Yqd.Enm;
using Newtonsoft.Json;

namespace Yqd.Core
{
    public class SuperviseHostService : BackgroundService
    {
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                var nt = DateTime.Now;
                //更新时间节点：8:30点 晚21-23  && nt.Minute >= 30
                if ((nt.Hour == 7 && nt.Minute >= 30) || (nt.Hour == 23 && nt.Minute >= 40))
                {
                    var ddService = Fn.GetService<DdService>();
                    var ctx = Fn.GetService<YqdContext>();
                    Logs.Information<SuperviseHostService>("任务预警滞后状态开始更新！");
                    nt = nt.Date;
                    var ids = new List<dynamic>();
                    var ds = new List<string>();
                    //未归档的任务
                    ds.AddRange(ctx.Yqd_SpecialSupervise.Where(it => !it.IsDel && it.Status != 任务状态.已完成 && !it.IsFinish && !it.IsArchive).Select(it => it.SuperviseID + "," + 事项类型.专项交办).ToList());
                    ds.AddRange(ctx.Yqd_Supervise.Where(it => it.IsDel == 0 && it.Status != 任务状态.已完成).Select(it => it.SuperviseID + "," + 事项类型.钉办督导).ToList());
                    ds.AddRange(ctx.Yqd_ExactSupervise.Where(it => !it.IsDel && it.Status != 任务状态.已完成).Select(it => it.SuperviseID + "," + 事项类型.精准督查).ToList());
                    ds.AddRange(ctx.Yqd_Coordinate.Where(it => it.IsDel == 0 && it.Status != 任务状态.已完成).Select(it => it.CoordinateID + "," + 事项类型.协同管理).ToList());
                    var assign = ctx.Yqd_Assign.Where(it => ds.Contains(it.ItemID + "," + it.ItemType)).ToList();
                    var aIDs = assign.Select(it => it.AssignID).ToArray();
                    var cIDs = ctx.Yqd_Scheme.Where(it => aIDs.Contains(it.AssignID) && it.CheckStatus == 审核状态.同意).Select(it => it.SchemeID).ToArray();

                    var planList = ctx.Yqd_JobPlan.Where(it => cIDs.Contains(it.SchemeID)).ToList();
                    var plan = planList.Where(it => cIDs.Contains(it.SchemeID) && it.PlanStatus != 工作计划状态.已完成).ToList();
                    var progress = ctx.Yqd_PlanProgress.Where(it => cIDs.Contains(it.SchemeID)).ToList();
                    //var progress = ctx.Yqd_PlanProgress.Where(it => cIDs.Contains(it.SchemeID) && it.CheckStatus == 审核状态.同意).ToList();
                    var app = ctx.Yqd_SchemeApproval.Where(it => aIDs.Contains(it.AssignID)).ToList();
                    var logs = ctx.Yqd_TaskLog.Where(it => it.Instime.Date == nt).ToList();
                    List<string> planContent = new List<string>();

                    foreach (var a in assign)
                    {
                        //完成时限
                        if (a.CompleteLimit < nt)
                        {
                            ids.Add(new
                            {
                                a.TaskID,
                                a.ItemID,
                                a.ItemType,
                                a.LeadUnit,
                                Tag = 1,
                                Status = 任务状态.滞后
                            });
                            continue;
                        }

                        //nt=2023-03-01 当天时限为预警 没有上报工作方案的按报审时限预警
                        if ((nt >= a.ReportLimit.AddDays(-3) && nt <= a.ReportLimit) && !app.Any(it => it.AssignID == a.AssignID))
                        {
                            ids.Add(new
                            {
                                a.TaskID,
                                a.ItemID,
                                a.ItemType,
                                a.LeadUnit,
                                Tag = 2,
                                Status = 任务状态.预警
                            });
                            continue;
                        }
                        //if (a.ReportLimit < nt && !app.Any(it => it.AssignID == a.AssignID))
                        //{
                        //    ids.Add(new
                        //    {
                        //        a.TaskID,
                        //        a.ItemID,
                        //        a.ItemType,
                        //        Tag = 2,
                        //        Status = 任务状态.预警
                        //    });
                        //    continue;
                        //}
                        if (!planList.Where(it => it.AssignID == a.AssignID).Any())
                        {
                            //未上报工作方案
                            //按报审时限判断是否滞后
                            if (a.ReportLimit < nt)
                            {
                                ids.Add(new
                                {
                                    a.TaskID,
                                    a.ItemID,
                                    a.ItemType,
                                    a.LeadUnit,
                                    Tag = 1,
                                    Status = 任务状态.滞后
                                });
                            }
                            continue;
                        }
                        var ps = plan.Where(it => it.AssignID == a.AssignID).ToList();
                        if (!ps.Any())
                        {
                            continue;
                        }
                        //1.先判断完成时限有无滞后
                        //2.报审时限预警
                        //3.未上报工作方案时 按报审时限判断滞后
                        //4.未填写进展反馈时，判断工作计划完成时限是否滞后、预警
                        //5.如果已反馈，并且没有完成且反馈状态是预警和滞后时，判断TimeLine
                        var bl = false;
                        foreach (var p in ps)
                        {
                            p.PlanStatus = 工作计划状态.未完成;

                            if (p.CompleteTime < nt)
                            {
                                p.PlanStatus = 工作计划状态.滞后;
                                ids.Add(new
                                {
                                    a.TaskID,
                                    a.ItemID,
                                    a.ItemType,
                                    a.LeadUnit,
                                    PlanID = p.PlanID.ToString(),
                                    dt = "",
                                    Tag = 4,
                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                    Status = 任务状态.滞后
                                });
                                bl = true;
                            }
                            //未填写进展反馈
                            if (!progress.Any(x => x.PlanID == p.PlanID))
                            {
                                if ((nt >= p.CompleteTime.AddDays(-3) && nt <= p.CompleteTime))
                                {
                                    p.PlanStatus = 工作计划状态.预警;
                                    ids.Add(new
                                    {
                                        a.TaskID,
                                        a.ItemID,
                                        a.ItemType,
                                        a.LeadUnit,
                                        IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                        dt = p.CompleteTime.ToString("yyyy-MM-dd"),
                                        PlanID = p.PlanID.ToString(),
                                        Tag = 3,
                                        Status = 任务状态.预警
                                    });
                                    bl = true;
                                }

                                if (bl) continue;
                            }

                            //上一条反馈审核后才有值TimeLine
                            if (!string.IsNullOrWhiteSpace(p.TimeLine))
                            {
                                var arr = p.TimeLine.Split(",");
                                var dt = DateTime.Parse(arr[arr.Length - 1]);//02-25
                                // 反馈状态是滞后或预警提醒
                                var t = progress.Any(it => it.PlanID == p.PlanID && (it.ProgressStatus == 0 || it.ProgressStatus == 任务状态.已完成 || it.ProgressStatus == 任务状态.正常推进));// && it.FeedbackTime == dt
                                // var t = progress.Any(it => it.PlanID == p.PlanID && (it.ProgressStatus == 0 || it.ProgressStatus == 任务状态.已完成 || it.ProgressStatus == 任务状态.正常推进));
                                var fl = !t;
                                if (fl)
                                {
                                    if (a.FeedbackLoop == 进展反馈周期.每月25日 || a.FeedbackLoop == 进展反馈周期.每月28日)
                                    {
                                        //3 ==4 no
                                        if (DateTime.Now.Month == dt.Month)
                                        {
                                            string timeLine = SuperviseService.GetFbLoopDate(a.FeedbackLoop, a.Instime, dt, a.Days);
                                            var dtTime = DateTime.Parse(timeLine);

                                            if (dtTime < nt)
                                            {
                                                p.PlanStatus = 工作计划状态.滞后;
                                                ids.Add(new
                                                {
                                                    a.TaskID,
                                                    a.ItemID,
                                                    a.ItemType,
                                                    a.LeadUnit,
                                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                    dt = dtTime.ToString("yyyy-MM-dd"),
                                                    PlanID = p.PlanID.ToString(),
                                                    Tag = 4,
                                                    Status = 任务状态.滞后
                                                });
                                                bl = true;
                                            }
                                            else if (nt >= dtTime.AddDays(-3) && nt <= dtTime) //3天内预警
                                            {
                                                p.PlanStatus = 工作计划状态.预警;
                                                ids.Add(new
                                                {
                                                    a.TaskID,
                                                    a.ItemID,
                                                    a.ItemType,
                                                    a.LeadUnit,
                                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                    dt = dtTime.ToString("yyyy-MM-dd"),
                                                    PlanID = p.PlanID.ToString(),
                                                    Tag = 3,
                                                    Status = 任务状态.预警
                                                });
                                                bl = true;
                                            }
                                        }
                                        else
                                        {
                                            //每月提醒
                                            //string timeLine = SuperviseService.GetFbLoopDate(a.FeedbackLoop, a.Instime, DateTime.Now, a.Days);

                                            string timeLine = SuperviseService.GetFbLoopDate(a.FeedbackLoop, a.Instime, DateTime.Now.Month > dt.Month ? DateTime.Now : dt, a.Days);
                                            var dtTime = DateTime.Parse(timeLine);
                                            if (dtTime < nt)
                                            {
                                                p.PlanStatus = 工作计划状态.滞后;
                                                ids.Add(new
                                                {
                                                    a.TaskID,
                                                    a.ItemID,
                                                    a.ItemType,
                                                    a.LeadUnit,
                                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                    dt = dtTime.ToString("yyyy-MM-dd"),
                                                    PlanID = p.PlanID.ToString(),
                                                    Tag = 4,
                                                    Status = 任务状态.滞后
                                                });
                                                bl = true;
                                            }
                                            else if (nt >= dtTime.AddDays(-3) && nt <= dtTime) //3天内预警
                                            {
                                                p.PlanStatus = 工作计划状态.预警;
                                                ids.Add(new
                                                {
                                                    a.TaskID,
                                                    a.ItemID,
                                                    a.ItemType,
                                                    a.LeadUnit,
                                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                    dt = dtTime.ToString("yyyy-MM-dd"),
                                                    PlanID = p.PlanID.ToString(),
                                                    Tag = 3,
                                                    Status = 任务状态.预警
                                                });
                                                bl = true;
                                            }
                                        }

                                    }
                                    else
                                    {
                                        if (dt < nt)
                                        {
                                            p.PlanStatus = 工作计划状态.滞后;
                                            ids.Add(new
                                            {
                                                a.TaskID,
                                                a.ItemID,
                                                a.ItemType,
                                                a.LeadUnit,
                                                IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                dt = dt.ToString("yyyy-MM-dd"),
                                                PlanID = p.PlanID.ToString(),
                                                Tag = 4,
                                                Status = 任务状态.滞后
                                            });
                                            bl = true;
                                        }
                                        else if (nt >= dt.AddDays(-3) && nt <= dt) //3天内预警
                                        {
                                            p.PlanStatus = 工作计划状态.预警;
                                            ids.Add(new
                                            {
                                                a.TaskID,
                                                a.ItemID,
                                                a.ItemType,
                                                a.LeadUnit,
                                                IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                dt = dt.ToString("yyyy-MM-dd"),
                                                PlanID = p.PlanID.ToString(),
                                                Tag = 3,
                                                Status = 任务状态.预警
                                            });
                                            bl = true;
                                        }
                                    }
                                }

                                if (!bl && progress.Any(it => it.PlanID == p.PlanID && (it.ProgressStatus == 0 || it.ProgressStatus == 任务状态.正常推进)))
                                {
                                    //当前任务未完成，取最新的反馈记录
                                    var newFb = progress.Where(it => it.PlanID == p.PlanID && (it.ProgressStatus == 任务状态.正常推进)).OrderByDescending(x => x.Instime).FirstOrDefault();
                                    if (newFb != null)
                                    {
                                        var fbTIme = newFb.Instime;
                                        if (a.FeedbackLoop == 进展反馈周期.每月25日 || a.FeedbackLoop == 进展反馈周期.每月28日)
                                        {

                                        }
                                        else
                                        {
                                            string timeLine = SuperviseService.GetFbLoopDate(a.FeedbackLoop, fbTIme, p.CompleteTime, a.Days);
                                            var dtTime = DateTime.Parse(timeLine);
                                            if (dtTime < nt)
                                            {
                                                p.PlanStatus = 工作计划状态.滞后;
                                                ids.Add(new
                                                {
                                                    a.TaskID,
                                                    a.ItemID,
                                                    a.ItemType,
                                                    a.LeadUnit,
                                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                    dt = dt.ToString("yyyy-MM-dd"),
                                                    PlanID = p.PlanID.ToString(),
                                                    Tag = 4,
                                                    Status = 任务状态.滞后
                                                });
                                                bl = true;
                                            }
                                            else if (nt >= dtTime.AddDays(-3) && nt <= dtTime) //3天内预警
                                            {
                                                p.PlanStatus = 工作计划状态.预警;
                                                ids.Add(new
                                                {
                                                    a.TaskID,
                                                    a.ItemID,
                                                    a.ItemType,
                                                    a.LeadUnit,
                                                    IsOne = a.FeedbackLoop == 进展反馈周期.一次性,
                                                    dt = dt.ToString("yyyy-MM-dd"),
                                                    PlanID = p.PlanID.ToString(),
                                                    Tag = 3,
                                                    Status = 任务状态.预警
                                                });
                                                bl = true;
                                            }
                                        }
                                    }
                                    if (!bl)
                                    {
                                        if (p.CompleteTime < nt)
                                        {
                                            p.PlanStatus = 工作计划状态.滞后;
                                            ids.Add(new
                                            {
                                                a.TaskID,
                                                a.ItemID,
                                                a.ItemType,
                                                a.LeadUnit,
                                                PlanID = p.PlanID.ToString(),
                                                dt = "",
                                                Tag = 4,
                                                Status = 任务状态.滞后
                                            });
                                            bl = true;
                                        }
                                    }
                                }
                                var isFinish = progress.Any(it => it.PlanID == p.PlanID && (it.ProgressStatus == 任务状态.已完成));// && it.FeedbackTime == dt
                                if (isFinish)
                                {
                                    p.PlanStatus = 工作计划状态.已完成;
                                }
                            }
                            planContent.Add($"planId={p.PlanID},planStatus={(int)p.PlanStatus}");
                        }
                        ctx.SaveChanges();
                        if (!bl)
                        {
                            if ((nt >= a.CompleteLimit.AddDays(-3) && nt <= a.CompleteLimit))
                            {
                                ids.Add(new
                                {
                                    a.TaskID,
                                    a.ItemID,
                                    a.ItemType,
                                    a.LeadUnit,
                                    Tag = 5,
                                    Status = 任务状态.预警
                                });
                                continue;
                            }

                        }
                        if (bl) continue;
                        ids.Add(new
                        {
                            a.TaskID,
                            a.ItemID,
                            a.ItemType,
                            a.LeadUnit,
                            Tag = 6,
                            Status = 任务状态.正常推进
                        });
                    }
                    var sql = "";
                    foreach (var m in ids.OrderBy(it => (int)it.Status))
                    {
                        var itype = (事项类型)m.ItemType;
                        var (TableName, KeyName) = SuperviseService.GetTableName(itype);
                        sql += string.Format("update " + TableName + " set [Status]={2} where " + KeyName + "={0} and [Status]!={1};", m.ItemID, (int)任务状态.已完成, (int)m.Status);
                        var IsJb = itype == 事项类型.专项交办;
                        var TaskID = IsJb ? m.ItemID : m.TaskID;
                        var cnt = "";

                        string typeName = m.ItemType.ToString();
                        var TaskName = "";
                        if (itype == 事项类型.专项交办 || itype == 事项类型.专项督查)
                        {
                            int tID = Convert.ToInt32(m.TaskID);
                            var t = ctx.Yqd_SpecialTask.FirstOrDefault(it => it.TaskID == tID);
                            if (t != null)
                            {
                                TaskName = t.Name;
                                typeName = t.TaskType.ToString();
                            }

                        }
                        else
                        {
                            long tID = Convert.ToInt64(m.TaskID);
                            var task = ctx.Yqd_Task.FirstOrDefault(it => it.TaskID == tID);
                            if (task != null) TaskName = task.TaskName;
                        }

                        List<string> employeeNames = new List<string>();

                        int itemId = m.ItemID;
                        var approval = ctx.Yqd_SchemeApproval.Where(it => it.ItemID == itemId && it.ItemType == itype).OrderByDescending(x => x.ApprovalID).FirstOrDefault();
                        if (approval != null)
                        {
                            if (!string.IsNullOrEmpty(approval.DeptLeader))
                            {
                                employeeNames.Add(approval.DeptLeader);
                            }
                            if (approval.DeptLeader != approval.Leader)
                            {
                                employeeNames.Add(approval.Leader);
                            }
                        }

                        switch (m.Tag)
                        {
                            case 1:
                                cnt = "任务已滞后";
                                if (logs.Any(it => it.TaskID == TaskID && it.IsJb == IsJb && it.Content == cnt)) continue;
                                TaskLogService.AddLog(TaskID, cnt, IsJb, false);

                                if (DateTime.Now.Hour == 7 && DateTime.Now.Minute >= 30)
                                {

                                    var msg = ddService.Notification(new List<string>(), typeName + "-滞后提醒", m.TaskID.ToString(), "任务名称: " + TaskName, "任务已滞后,请及时办理。", pushStep: 推送流程.任务交办预警和滞后, unitCode: m.LeadUnit.ToString(), superId: itemId, employeeNames: employeeNames);

                                    Logs.Information<SuperviseHostService>(itemId + "," + typeName + "发送了滞后通知，返回值：" + msg);
                                }

                                break;
                            case 5:
                                cnt = "任务已预警";
                                if (logs.Any(it => it.TaskID == TaskID && it.IsJb == IsJb && it.Content == cnt)) continue;
                                TaskLogService.AddLog(TaskID, cnt, IsJb, false);
                                if (DateTime.Now.Hour == 7 && DateTime.Now.Minute >= 30)
                                {

                                    var msg2 = ddService.Notification(new List<string>(), typeName + "-预警提醒", m.TaskID.ToString(), "任务名称: " + TaskName, "任务已预警,请及时办理。", pushStep: 推送流程.任务交办预警和滞后, unitCode: m.LeadUnit.ToString(), superId: m.ItemID, employeeNames: employeeNames);

                                    Logs.Information<SuperviseHostService>(itemId + "," + typeName + "发送了预警通知，返回值：" + msg2);
                                }
                                break;
                            case 2:
                                cnt = "任务预警(工作方案未及时报审)";
                                if (logs.Any(it => it.TaskID == TaskID && it.IsJb == IsJb && it.Content == cnt)) continue;
                                TaskLogService.AddLog(TaskID, cnt, IsJb, false);
                                if (DateTime.Now.Hour == 7 && DateTime.Now.Minute >= 30)
                                {

                                    var msg2 = ddService.Notification(new List<string>(), typeName + "-预警提醒", m.TaskID.ToString(), "任务名称: " + TaskName, "任务已预警,请及时办理。", pushStep: 推送流程.任务交办预警和滞后, unitCode: m.LeadUnit.ToString(), superId: m.ItemID, employeeNames: employeeNames);

                                    Logs.Information<SuperviseHostService>(itemId + "," + typeName + "发送了预警通知，返回值：" + msg2);
                                }
                                break;
                            case 3:
                                var id = int.Parse(m.PlanID);
                                var pl = plan.FirstOrDefault(it => it.PlanID == id);
                                if (pl != null)
                                {
                                    cnt = "任务预警(工作计划:" + pl.Measure + "," + (m.IsOne ? "" : m.dt) + "期进展情况未及时反馈)";
                                    if (logs.Any(it => it.TaskID == TaskID && it.IsJb == IsJb && it.Content == cnt)) continue;
                                    TaskLogService.AddLog(TaskID, cnt, IsJb, false);
                                    if (DateTime.Now.Hour == 7 && DateTime.Now.Minute >= 30)
                                    {

                                        var msg3 = ddService.Notification(new List<string>(), typeName + "-预警提醒", m.TaskID.ToString(), "任务名称: " + TaskName, "任务已预警,请及时办理。", pushStep: 推送流程.任务交办预警和滞后, unitCode: m.LeadUnit.ToString(), superId: m.ItemID, employeeNames: employeeNames);

                                        Logs.Information<SuperviseHostService>(itemId + "," + typeName + "发送了预警通知，返回值：" + msg3);
                                    }
                                }
                                break;
                            case 4:
                                id = int.Parse(m.PlanID);
                                pl = plan.FirstOrDefault(it => it.PlanID == id);
                                if (pl != null)
                                {
                                    cnt = "工作计划(" + pl.Measure + ")" + (m.dt != "" ? "," + m.dt + "期进展情况" : "") + "已滞后";
                                    if (logs.Any(it => it.TaskID == TaskID && it.IsJb == IsJb && it.Content == cnt)) continue;
                                    TaskLogService.AddLog(TaskID, cnt, IsJb, false);
                                    if (DateTime.Now.Hour == 7 && DateTime.Now.Minute >= 30)
                                    {
                                        var msg4 = ddService.Notification(new List<string>(), typeName + "-滞后提醒", m.TaskID.ToString(), "任务名称: " + TaskName, "任务已滞后,请及时办理。", pushStep: 推送流程.任务交办预警和滞后, unitCode: m.LeadUnit.ToString(), superId: m.ItemID, employeeNames: employeeNames);

                                        Logs.Information<SuperviseHostService>(itemId + "," + typeName + "发送了滞后通知，返回值：" + msg4);
                                    }
                                }
                                break;
                        }
                    }
                    var ret = 0;
                    if (sql != "")
                    {
                        Logs.Information<SuperviseHostService>($"任务预警滞后状态更新语句：{sql}");
                        ret = ctx.Database.ExecuteSql(sql);
                    }
                    if (planContent.Any())
                    {
                        Logs.Information<SuperviseHostService>($"工作计划数据更新：{string.Join(";", planContent)}");
                    }
                    Logs.Information<SuperviseHostService>("任务预警滞后状态更新完成！本次更新" + ret + "条。");
                }
                Thread.Sleep(3000);
                await Task.Delay(5000, stoppingToken);
            }
        }
    }
}
